#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "stack.h"

void stack_create (Stack *stack, int mem_size)
{
  stack->stack = malloc (4 * mem_size);
  assert (stack->stack);
  stack->size = 4;
  stack->top = -1;
  stack->mem_size = mem_size;
}

void stack_destroy (Stack *stack)
{
  free (stack->stack);
  stack->stack = NULL;
  stack->size = 0;
  stack->top = -1;
  stack->mem_size = 0;
}

void * stack_top (Stack *stack)
{
  if (stack->top < 0)
    return NULL;

  return stack->stack + stack->top * stack->mem_size;
}

void stack_push (Stack *stack, void *item)
{
  if (stack->top + 1 >= stack->size)
    stack_resize (stack);

  ++stack->top;
  memcpy (stack->stack + stack->top * stack->mem_size, item, stack->mem_size);
}

void stack_pop (Stack *stack)
{
  if (stack->top < 0)
    return;

  --stack->top;
}

void stack_resize (Stack *stack)
{
  stack->stack = realloc (stack->stack, stack->size * 2 * stack->mem_size);
  assert (stack->stack);
  stack->size *= 2;
}
